<script lang="ts" setup>
import {reactive, ref, toRaw} from 'vue';
import {connectDBAPI, getDBListAPI} from "@/apis/db.ts";
import {generateCodeAPI} from "@/apis/generate.ts";
import {message} from "ant-design-vue";
import type {Rule} from "ant-design-vue/es/form";

interface FormState {
  mysqlStatus: string;
  mysqlName: string;
  username: string;
  password: string;
  packageName: string;
}

const formState = reactive<FormState>({
  mysqlStatus: '数据库-未连接',
  mysqlName: '',
  username: 'root',
  password: 'root',
  packageName: ''
});
const rules: Record<string, Rule[]> = {
  mysqlName: [{required: true, message: '请输入数据库名称!'}],
  packageName: [{required: true, message: '请输入生成的包名!'}],
  username: [{required: true, message: '请输入数据库用户名!'}],
  password: [{required: true, message: '请输入数据库密码!'}],

};
const formRef = ref();
const onSubmit = () => {
  console.log('submit!', toRaw(formState));
  formRef.value
      .validate()
      .then(() => {
        connectDBAPI({
          mysqlName: formState.mysqlName,
          username: formState.username,
          password: formState.password,
        }).then(res => {
          if (res.data.flag) {
            message.success('数据库连接成功')
            formState.mysqlStatus = '数据库-已连接'
          } else {
            formState.mysqlStatus = '数据库-连接失败'
          }
        })
      })
};

//获取表数据

const tableData = ref<tableDataItem[]>([]);

interface tableDataItem {
  key?: number;
  tableName: string;
  enName: string;
  serviceName: string;
  mapperName: string;
  controllerName: string;
  packageName: string;
  columns: innerDataItem[],
  vos: innerDataItem[],
  dtos: innerDataItem[],
}

const columns = [
  {
    title: '序号',
    dataIndex: 'key',
    width: 200,
  },
  {
    title: '表名',
    dataIndex: 'tableName',
    width: 300,
  },
  {
    title: 'en_类',
    dataIndex: 'enName',
    width: 300,
  },
  {
    title: 'Mapper',
    dataIndex: 'mapperName',
    width: 300,
  },
  {
    title: 'Service',
    dataIndex: 'serviceName',
    width: 300,
  },
  {
    title: 'Controller',
    dataIndex: 'controllerName',
    width: 300,
  },
];

interface innerDataItem {
  upgradeNum?: number;
  key?: number;
  propertyName: string;
  columnName: string;
  type: string;
  remark: string;
  primary?: boolean;
  isVo?: boolean;
  isDto?: boolean;
}

const innerData: innerDataItem[] = [];
const innerColumns = [
  {title: '字段名称', dataIndex: 'columnName', key: 'columnName', width: 200,},
  {title: '数据类型', dataIndex: 'type', width: 200,},
  {title: '字段注释', dataIndex: 'remark', width: 200,},
  {
    title: 'Action',
    dataIndex: 'operation',
    key: 'operation',
    width: 200,
  },
];
const getDBList = () => {
  getDBListAPI({
    packageName: formState.packageName
  }).then(res => {
    if (res.data.flag) {
      tableData.value = res.data.data.map((item: any, index: number) => {
        return {
          ...item,
          key: index + 1,
          vos: [],
          dtos: [],
        }
      })

    }
    console.log(res)
  })
}


//生成代码
const pathName = ref<string>("C:\\Users\\19324\\Desktop")//生成地址
const generateCode = () => {
  generateCodeAPI({
    tableClassList: tableData.value,
    pathName: pathName.value,
  }).then(res => {
    console.log(res)
    if (res.data.flag) {
      message.success('生成成功')
    }
  })
}
const expandedRowKeys = ref<number[]>([]);
//打开的行
const onExpand = (expanded: boolean, record: any) => {
  if (expanded) {
    // 行展开时的逻辑
    if (!expandedRowKeys.value.includes(record.key)) {
      expandedRowKeys.value = [...expandedRowKeys.value, record.key];
    }
  } else {
    // 行收起时的逻辑
    expandedRowKeys.value = expandedRowKeys.value.filter(key => key !== record.key);
    innerData.splice(0, innerData.length);
  }
};
//子集获取数据
const getInnerData = (record: any): innerDataItem[] => {
  const innerData: innerDataItem[] = [];
  // 根据父行数据动态生成子集数据
  for (let i = 0; i < record.columns.length; i++) {
    innerData.push({
      upgradeNum: record.key - 1,
      key: i,
      propertyName: record.columns[i].propertyName,
      columnName: record.columns[i].columnName,
      type: record.columns[i].type,
      remark: record.columns[i].remark,
      isVo: record.columns[i].isVo,
      isDto: record.columns[i].isDto
    })
  }
  return innerData;
};
const Vo = (column: any) => {
  if (!column.isVo) {
    tableData.value[column.upgradeNum].vos.push({
      key: column.key,
      propertyName: column.propertyName,
      columnName: column.columnName,
      type: column.type,
      remark: column.remark,
    })
    tableData.value[column.upgradeNum].columns[column.key].isVo = true
  } else {
    tableData.value[column.upgradeNum].vos = tableData.value[column.upgradeNum].vos.filter(item => item.key !== column.key)
    tableData.value[column.upgradeNum].columns[column.key].isVo = false
  }

}
const Dto = (column: any) => {
  if (!column.isDto) {
    tableData.value[column.upgradeNum].dtos.push({
      key: column.key,
      propertyName: column.propertyName,
      columnName: column.columnName,
      type: column.type,
      remark: column.remark,
    })
    tableData.value[column.upgradeNum].columns[column.key].isDto = true
  } else {
    tableData.value[column.upgradeNum].dtos = tableData.value[column.upgradeNum].dtos.filter(item => item.key !== column.key)
    tableData.value[column.upgradeNum].columns[column.key].isDto = false
  }

}
</script>

<template>
  <div class="home">
    <div>
      <h2>代码生成器</h2>
      <div>
        <h5>数据库{{ formState.mysqlStatus }}</h5>
      </div>
    </div>
    <div class="config">

      <div>
        <a-form
            ref="formRef"
            :label-col="{ span: 8 }"
            :model="formState"
            :rules="rules"
            :wrapper-col="{ span: 16 }"
            layout="inline"
        >
          <a-form-item
              label="数据库名称"
              name="mysqlName"
          >
            <a-input v-model:value="formState.mysqlName"/>
          </a-form-item>


          <a-form-item
              label="生成包名"
              name="packageName"
          >
            <a-input v-model:value="formState.packageName"/>
          </a-form-item>
          <a-form-item
              :rules="[{ required: true, message: 'Please input your username!' }]"
              label="数据库用户名"
              name="username"
          >
            <a-input v-model:value="formState.username"/>
          </a-form-item>
          <a-form-item
              label="密码"
              name="password"
          >
            <a-input v-model:value="formState.password"/>
          </a-form-item>

          <a-form-item :wrapper-col="{ offset: 8, span: 16 }">
            <a-button style="width: 200px" type="primary" @click="onSubmit">连接</a-button>
          </a-form-item>
        </a-form>
      </div>
    </div>
    <div class="table">
      <div class="package">
      </div>
      <div style="display: flex;justify-content: space-around;width: 80%">
        <a-button style="width: 200px" type="primary" @click="getDBList">读取表</a-button>
        <a-input v-model:value="pathName" placeholder="生成地址" style="width: 300px"></a-input>
        <a-button style="width: 200px" type="primary" @click="generateCode">生成代码</a-button>
      </div>
      <div class="table_list">
        <a-table
            :columns="columns"
            :data-source="tableData"
            :expandedRowKeys="expandedRowKeys"
            class="components-table-demo-nested"
            @expand="onExpand">
          <template #expandedRowRender="{ record }">
            <a-table
                :columns="innerColumns"
                :data-source="getInnerData(record)"
                :pagination="false">
              <template #bodyCell="{ column, record: innerRecord }">
                <template v-if="column.key === 'operation'">
        <span class="table-operation" style="display: flex;justify-content: space-around">
          <a-button v-if="!innerRecord.isVo" ghost type="primary" @click="Vo(innerRecord)">添加 VO</a-button>
          <a-button v-else danger @click="Vo(innerRecord)">移除 VO</a-button>

          <a-button v-if="!innerRecord.isDto" ghost type="primary" @click="Dto(innerRecord)">添加 DTO</a-button>
          <a-button v-else danger @click="Dto(innerRecord)">移除 DTO</a-button>
        </span>
                </template>
              </template>
            </a-table>
          </template>
        </a-table>
      </div>
    </div>
  </div>

</template>

<style scoped>
.home {
  border: 1px solid red;
  padding: 10px;
  width: 100%;
  height: 100vh;
  background-color: #f0f2f5;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-sizing: border-box; /* 添加 box-sizing 属性 */
  overflow-x: hidden; /* 隐藏水平滚动条 */

  h2 {
    font-size: 30px;
    font-weight: bold;
    color: #333;
  }

  .config {
    width: 100%;
    height: 80px;
    background-color: #fff;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: space-around;
  }

  .table {
    width: 100%;
    height: auto;
    margin-top: 10px;
    padding-top: 10px;
    background-color: #fff;
    border: 1px solid #ccc;
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    justify-items: center;
    align-items: center;

    .table_list {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
  }
}
</style>
